package com.fmi.timedealer;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.fmi.timedealer.datamanager.IDataManager;
import com.fmi.timedealer.datamanager.SQLiteDataManager;
import com.fmi.timedealer.track.TrackPastEventActivity;

import android.app.AlertDialog;
import android.app.ExpandableListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.Toast;

public class CategoriesViewActivity extends ExpandableListActivity {

	private static final int CREATE_ACTIVITY_ITEM_CODE = 1;
	private static final int EDIT_ACTIVITY_ITEM_CODE = 2;
	private static final int CREATE_CATEGORY_CODE = 3;
	private static final int EDIT_CATEGORY_ITEM_CODE = 4;

	// needed for activity that will be called by this one
	private String selectedCategory = null;
	private ActivityItem activityToEdit = null;
	private Category categoryToEdit = null;

	private ExpandableListAdapter adapter;

	private IDataManager dbManager = null;

	private List<Category> groups = new ArrayList<Category>(); // categories
	private List<List<ActivityItem>> children = new ArrayList<List<ActivityItem>>(); // activities for a category

	@Override
	public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);

		dbManager = new SQLiteDataManager("MyDB", this);

		// Set up the adapter
		adapter = new MyExpandableListAdapter();
		setListAdapter(adapter);
		registerForContextMenu(getExpandableListView());

		// modify lines dividers
		int[] colors = { 0, Color.GRAY, 0 };
		getExpandableListView().setDivider(new GradientDrawable(Orientation.RIGHT_LEFT, colors));
		getExpandableListView().setDividerHeight(2);
		getExpandableListView().setChildDivider(new ColorDrawable(Color.WHITE));
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {

		ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuInfo;

		String title = null;

		// if an activity item is selected
		if (ExpandableListView.getPackedPositionType(info.packedPosition) == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
			title = ((TextView)info.targetView.findViewById(R.id.activityName)).getText().toString();
			menu.setHeaderTitle(title);
			menu.add(0, 0, 0, "Edit");
			menu.add(1, 1, 1, "Delete");
			menu.add(2, 2, 2, "Start Tracking");
			menu.add(3, 3, 3, "Track Past Event");
		}
		// if a category is selected
		if (ExpandableListView.getPackedPositionType(info.packedPosition) == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
			title = ((TextView) info.targetView).getText().toString();
			menu.setHeaderTitle("Category " + title);
			menu.add(0, 0, 0, "Edit");
			menu.add(1, 1, 1, "Delete");
			menu.add(2, 2, 2, "Add Activity");
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {

		ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo();
		int type = ExpandableListView.getPackedPositionType(info.packedPosition);

		switch (item.getItemId()) {
		case 0: { // Edit
			// Edit Activity Item
			if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { 
				int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
				int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition);

				selectedCategory = null;
				activityToEdit = children.get(groupPos).get(childPos);

				Intent i = new Intent(CategoriesViewActivity.this, ActivityItemActivity.class);
				i.putExtra(ActivityItemActivity.ACTIVITY_TO_EDIT_KEY, activityToEdit);
				i.putExtra(ActivityItemActivity.SELECTED_CATEGORY, selectedCategory);
				startActivityForResult(i, EDIT_ACTIVITY_ITEM_CODE);
			}
			// Edit Category
			if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { 
				int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
				
				categoryToEdit = groups.get(groupPos);
				
				Intent i = new Intent(CategoriesViewActivity.this, CategoryActivity.class);
				i.putExtra(CategoryActivity.CATEGORY_TO_EDIT, categoryToEdit);
				startActivityForResult(i, EDIT_CATEGORY_ITEM_CODE);
			}
			return true;
		}
		case 1: { // Delete
			// Delete Activity Item
			if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { 
				int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
				int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition);

				ActivityItem activityToDelete = children.get(groupPos).get(childPos);
				boolean success = dbManager.deleteActivityItem(activityToDelete);
				if (success) {
					Toast.makeText(getApplicationContext(), "Successfully deleted activity '"
						+ children.get(groupPos).get(childPos).getName() + "'", Toast.LENGTH_SHORT).show();
					refreshListAfterActivityItemDelete(activityToDelete);
				} else {
					Toast.makeText(getApplicationContext(), "A technical problem occured, activity is not deleted",
						Toast.LENGTH_SHORT).show();
				}
			}
			// Delete Category
			if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { 
				int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
				
				Category categoryToDelete = groups.get(groupPos);
				showDelteConfirmationDialog(categoryToDelete);
			}
			return true;
		}
		case 2: { 
			
			if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
				// Add Activity
				int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);

				selectedCategory = groups.get(groupPos).getName();
				activityToEdit = null;

				Intent i = new Intent(CategoriesViewActivity.this, ActivityItemActivity.class);
				i.putExtra(ActivityItemActivity.ACTIVITY_TO_EDIT_KEY, activityToEdit);
				i.putExtra(ActivityItemActivity.SELECTED_CATEGORY, selectedCategory);
				startActivityForResult(i, CREATE_ACTIVITY_ITEM_CODE);
			}
			
			// Start Tracking Time for activity
			if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {

				int groupPos = ExpandableListView
						.getPackedPositionGroup(info.packedPosition);
				int childPos = ExpandableListView
						.getPackedPositionChild(info.packedPosition);

				ActivityItem activityToTrack = children.get(groupPos).get(
						childPos);
				if (!dbManager.isActivityRunning(activityToTrack)) {
					boolean success = dbManager.trackTime(activityToTrack,
							new Date(), null);
					if (success) {
						Toast.makeText(
								getApplicationContext(),
								"Successfully started tracking time for action "
										+ activityToTrack.getName(),
								Toast.LENGTH_SHORT).show();
					} else {
						Toast.makeText(
								getApplicationContext(),
								"Failed to start tracking time for action "
										+ activityToTrack.getName(),
								Toast.LENGTH_SHORT).show();
					}
				} else {
					Toast.makeText(getApplicationContext(), "Selected action is already running: "
							+ activityToTrack.getName(), Toast.LENGTH_SHORT).show();
				}
			}
			return true;
		}
		case 3: {
			// Track Past Event for activity
			if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {

				int groupPos = ExpandableListView
						.getPackedPositionGroup(info.packedPosition);
				int childPos = ExpandableListView
						.getPackedPositionChild(info.packedPosition);

				ActivityItem activityToTrack = children.get(groupPos).get(
						childPos);
				Intent i = new Intent(CategoriesViewActivity.this, TrackPastEventActivity.class);
				i.putExtra(ActivityItem.ACTIVITY_ITEM, activityToTrack);
				startActivity(i);
			}
			return true;
		}
		default:
			return super.onContextItemSelected(item);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.add_category, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {

		case R.id.add_category: {
			Intent i = new Intent(CategoriesViewActivity.this, CategoryActivity.class);
			categoryToEdit = null;
			i.putExtra(CategoryActivity.CATEGORY_TO_EDIT, categoryToEdit);
			startActivityForResult(i, CREATE_CATEGORY_CODE);
			return true;
		}
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	private class MyExpandableListAdapter extends BaseExpandableListAdapter {

		public MyExpandableListAdapter() {

			groups = dbManager.getAllCategories();
			for (Category category : groups) {
				children.add(dbManager.getActivitiesForCategory(category.getName()));
			}
		}

		public Object getChild(int groupPosition, int childPosition) {
			return children.get(groupPosition).get(childPosition).getName();
		}

		public long getChildId(int groupPosition, int childPosition) {
			return childPosition;
		}

		public int getChildrenCount(int groupPosition) {
			return children.get(groupPosition).size();
		}

		public TextView getGenericView() {
			
			// Layout parameters for the ExpandableListView
			AbsListView.LayoutParams lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 74);

			TextView textView = new TextView(CategoriesViewActivity.this);
			textView.setLayoutParams(lp);
			// Center the text vertically
			textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
			// Set the text starting position
			textView.setPadding(55, 0, 0, 0);
			return textView;
		}

		public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
				View convertView, ViewGroup parent) {
			
//			TextView textView = getGenericView();
//			textView.setBackgroundColor(Color.DKGRAY);
//			textView.setText(getChild(groupPosition, childPosition).toString());
//			return textView;
			
			View v = convertView;
            if (v == null) {
                LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(R.layout.activity_item_row, null);              
            }
            
            ActivityItem activityItem = children.get(groupPosition).get(childPosition);

            if (activityItem != null) {
                    TextView tvName = (TextView)v.findViewById(R.id.activityName);
                    TextView tvDescription = (TextView)v.findViewById(R.id.activityDescription);
                   
                    if (tvName != null) {
                    	tvName.setText(activityItem.getName());
                    	tvName.setBackgroundColor(Color.DKGRAY);
                	}
                    if (tvDescription != null){
                    	tvDescription.setText(activityItem.getDescription());
                    	tvDescription.setBackgroundColor(Color.DKGRAY);
                    }
            }
        	v.setBackgroundColor(Color.DKGRAY);
            return v;
		}

		public Object getGroup(int groupPosition) {
			return groups.get(groupPosition).getName();
		}

		public int getGroupCount() {
			return groups.size();
		}

		public long getGroupId(int groupPosition) {
			return groupPosition;
		}

		public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
			
			TextView textView = getGenericView();
			textView.setText(getGroup(groupPosition).toString());
			return textView;
		}

		public boolean isChildSelectable(int groupPosition, int childPosition) {
			return true;
		}

		public boolean hasStableIds() {
			return true;
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {

		if (requestCode == EDIT_ACTIVITY_ITEM_CODE) {
			if (resultCode == RESULT_OK) {			
				Bundle extras = data.getExtras();
				ActivityItem item = (ActivityItem) extras.getSerializable(ActivityItemActivity.RESULT_ACTIVITY_ITEM);			
				refreshListAfterActivityItemEdited(item);
				return;
			}
		}
		
		if (requestCode == CREATE_ACTIVITY_ITEM_CODE) {
			if (resultCode == RESULT_OK) {			
				Bundle extras = data.getExtras();
				ActivityItem item = (ActivityItem) extras.getSerializable(ActivityItemActivity.RESULT_ACTIVITY_ITEM);			
				refreshListAfterActivityItemCreated(item);
				return;
			}
		}
		
		if (requestCode == CREATE_CATEGORY_CODE) {
			if (resultCode == RESULT_OK) {			
				Bundle extras = data.getExtras();
				Category category = (Category) extras.getSerializable(CategoryActivity.REULT_CATEGORY);			
				refreshListAfterCategoryCreated(category);
				return;
			}
		}
		
		if (requestCode == EDIT_CATEGORY_ITEM_CODE) {
			if (resultCode == RESULT_OK) {			
				Bundle extras = data.getExtras();
				Category category = (Category) extras.getSerializable(CategoryActivity.REULT_CATEGORY);			
				refreshListAfterCategoryEdited(category);
				return;
			}
		}
	}
	
	private void refreshListAfterActivityItemCreated(ActivityItem activityItem) {	
		refreshData();
		getExpandableListView().expandGroup(getCategoryPosition(activityItem.getCategory()));		
	}

	private void refreshListAfterActivityItemDelete(ActivityItem activityItem) {
		refreshData();
	}
	
	private void refreshListAfterActivityItemEdited(ActivityItem activityItem) {
		refreshData();
		getExpandableListView().expandGroup(getCategoryPosition(activityItem.getCategory()));
	}
	
	private void refreshListAfterCategoryDeleted(Category category) {	
		refreshData();
	}
	
	private void refreshListAfterCategoryEdited(Category category) {
		refreshData();
	}
	
	private void refreshListAfterCategoryCreated(Category category) {
		refreshData();
	}
	
	private void showDelteConfirmationDialog(final Category categoryToDelete) {
		
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage("All activities from the category will be deleted too. \n" +
				"Are you sure you want to delete this category?")
		       .setCancelable(false)
		       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
		        	   deleteCategory(categoryToDelete);
		           }
		       })
		       .setNegativeButton("No", new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
		                dialog.cancel();
		           }
		       });
		AlertDialog alert = builder.create();
		alert.show();
	}

	protected void deleteCategory(Category categoryToDelete) {
		
		boolean success = dbManager.deleteCategory(categoryToDelete);
		
		if (success) {
			Toast.makeText(getApplicationContext(), "Successfully deleted category '" +
				categoryToDelete.getName() + "'", Toast.LENGTH_SHORT).show();
			refreshListAfterCategoryDeleted(categoryToDelete);
		} else {
			Toast.makeText(getApplicationContext(), "A technical problem occured, category is not deleted",
				Toast.LENGTH_SHORT).show();
		}
	}
	
	private void refreshData() {
		
		groups = dbManager.getAllCategories();
		children = new ArrayList<List<ActivityItem>>();
		for (Category cc : groups) {
			children.add(dbManager.getActivitiesForCategory(cc.getName()));
		}
		((BaseExpandableListAdapter) adapter).notifyDataSetChanged();
	}
	
	private int getCategoryPosition(String catgeoryName) {
		
		int categoryPosition = 0;
		for(Category current : groups) {
			if(current.getName().equals(catgeoryName)) {
				break;
			}
			categoryPosition++;
		}
		
		return categoryPosition;
	}
}
